package fun.flyee.android.pengshan.services;

import android.app.Notification;
import android.content.Context;
import android.os.Build;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.model.LatLng;
import com.amap.api.trace.LBSTraceClient;
import com.amap.api.trace.TraceLocation;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import fun.flyee.android.pengshan.AppContex;
import fun.flyee.android.pengshan.api.ApiClient;
import fun.flyee.android.pengshan.utils.Logger;
import fun.flyee.android.pengshan.utils.NotificationUtilsTimer;
import fun.flyee.pengshan.social.R;

public class TraceTracker implements Tracker, AMapLocationListener {

    private Context mContext;
    private AMapLocationClient mLocationClient;
    private LBSTraceClient mTraceClient;
    private List<TraceLocation> locs = new ArrayList<>();
    private String userName;

    public TraceTracker(Context context, String userName) {
        this.mContext = context;
        this.userName = userName;
        try {
            mTraceClient = LBSTraceClient.getInstance(context);
            mLocationClient = new AMapLocationClient(context);
            AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
            mLocationClient.setLocationListener(this);
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Device_Sensors);
            mLocationOption.setInterval(3000);
            mLocationClient.enableBackgroundLocation(2, getNotification());
            mLocationClient.setLocationOption(mLocationOption);
        } catch (Exception e) {
            Logger.e("trace init failed", e);
        }
    }

    private Notification getNotification() {
        Notification notification = null;
        if (Build.VERSION.SDK_INT >= 26) {
            NotificationUtilsTimer notificationUtilsTimer = new NotificationUtilsTimer(AppContex.getContext());
            Notification.Builder builder = notificationUtilsTimer.getAndroidChannelNotification(mContext.getString(R.string.app_name), "持续定位中");
            builder.setSmallIcon(R.mipmap.ic_work);
            builder.setAutoCancel(false);
            notification = builder.build();
        } else {
            //获取一个Notification构造器
            Notification.Builder builder = new Notification.Builder(mContext);

            builder.setContentTitle(mContext.getString(R.string.app_name)) // 设置下拉列表里的标题
                    .setAutoCancel(false)
                    .setSmallIcon(R.mipmap.ic_work) // 设置状态栏内的小图标
                    .setContentText(mContext.getString(R.string.running)) // 设置上下文内容
                    .setWhen(System.currentTimeMillis()); // 设置该通知发生的时间

            notification = builder.build(); // 获取构建好的Notification
        }
        return notification;
    }

    @Override
    public void start() {
        mLocationClient.startLocation();
    }

    @Override
    public void fetch(FetchCallback callback) {
        Logger.i("traceTracker", "origin count: " + locs.size());
        if (locs.size() < 2) {
            return;
        }
        List<TraceLocation> tmp = locs;
        locs = new ArrayList<>();
        int lineId = (int) System.currentTimeMillis() / 1000;
        queryTrace(lineId, tmp, new AtomicInteger(0), callback);
    }

    @Override
    public void getLast(FetchCallback callback) {

    }

    private void queryTrace(int lineId, List<TraceLocation> tmp, AtomicInteger retry, FetchCallback callback) {
        mTraceClient.queryProcessedTrace(lineId, tmp, LBSTraceClient.TYPE_AMAP, new TraceResultListener() {
            @Override
            public void onFinished(int lineId, List<LatLng> list, int distance, int spendTime) {
                if (list != null && list.size() > 0) {
                    Logger.i("traceTracker", "result count: " + list.size());
                    for (LatLng ll : list) {
                        Logger.i("traceTracker", "position: " + ll.latitude + ", " + ll.longitude);
                    }
                    callback.fetch(list);
                } else {
                }
            }

            @Override
            public void onRequestFailed(int i, String s) {
                if (retry.get() <= 3) {
                    retry.incrementAndGet();
                    queryTrace(lineId, tmp, retry, callback);
                }
            }
        });
    }

    @Override
    public void destroy() {
        locs.clear();
        if (mTraceClient != null) {
            mTraceClient.stopTrace();
            mTraceClient.destroy();
            mTraceClient = null;
        }
        if (mLocationClient != null) {
            mLocationClient.disableBackgroundLocation(true);
            mLocationClient.stopLocation();
            mLocationClient.onDestroy();
            mLocationClient = null;
        }
    }

    @Override
    public void onLocationChanged(AMapLocation location) {
        if (location.getLatitude() == 0 || location.getLongitude() == 0) return;
        if (locs.size() > 0) {
            TraceLocation prev = locs.get(locs.size() - 1);
            if (prev.getLatitude() == location.getLatitude() && prev.getLongitude() == location.getLongitude()) {
                return;
            }
        }
        locs.add(parseTraceLocation(location));
    }

    private TraceLocation parseTraceLocation(AMapLocation amapLocation) {
        TraceLocation location = new TraceLocation();
        location.setBearing(amapLocation.getBearing());
        location.setLatitude(amapLocation.getLatitude());
        location.setLongitude(amapLocation.getLongitude());
        location.setSpeed(amapLocation.getSpeed());
        location.setTime(amapLocation.getTime());
        return location;
    }

}
